package org.xhy.circuitbreaker;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.xhy.circuitbreaker.proxy.CglibFactory;

import java.lang.reflect.Method;
import java.util.HashSet;

/**
 * @description:
 * @gitee: https://gitee.com/XhyQAQ
 * @copyright: B站: https://space.bilibili.com/152686439
 * @Author: Xhy
 * @CreateTime: 2024-06-04 16:36
 */
@Configuration
public class CircuitBreakerBeanPostProcessor implements BeanPostProcessor {

    private ICircuitBreakerController iCircuitBreakerController;

    public CircuitBreakerBeanPostProcessor(ICircuitBreakerController iCircuitBreakerController){
        this.iCircuitBreakerController = iCircuitBreakerController;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // 找到方法标有注解的收集
        final Class<?> aClass = bean.getClass();
        final HashSet<Integer> methodsHashCode = new HashSet<>();
        for (Method method : aClass.getDeclaredMethods()) {
            if (method.isAnnotationPresent(CircuitBreaker.class)) {
                methodsHashCode.add(method.hashCode());
            }
        }

        if (!methodsHashCode.isEmpty()){
            try {
                return CglibFactory.getProxy(bean,methodsHashCode,iCircuitBreakerController);
            } catch (NoSuchFieldException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }

        return bean;
    }

}
